package com.xhj.mybatis.reflection.wrapper;

import com.xhj.mybatis.reflection.MetaObject;
import com.xhj.mybatis.reflection.property.PropertyTokenizer;

import java.util.List;
import java.util.Map;

/**
 * BaseWrapper
 *
 * @author XJks
 * @description BaseWrapper 是一个抽象类，实现了 ObjectWrapper 接口。主要用于对集合类型（如 List、Map、数组等）进行统一的属性访问和操作。
 */
public abstract class BaseWrapper implements ObjectWrapper {

    /**
     * 定义一个空参数数组常量，通常用于反射调用方法时传递空参数
     */
    protected static final Object[] NO_ARGUMENTS = new Object[0];

    /**
     * 持有一个 MetaObject 对象的引用，用于反射操作目标对象
     */
    protected final MetaObject metaObject;

    /**
     * 构造方法，初始化 metaObject 字段
     *
     * @param metaObject 反射操作的元对象
     */
    protected BaseWrapper(MetaObject metaObject) {
        this.metaObject = metaObject;
    }

    /**
     * 解析集合对象。
     * 如果属性名为空字符串，直接返回传入的对象；
     * 否则通过 metaObject 获取指定属性的值。
     *
     * @param prop   属性分词器，包含属性名等信息
     * @param object 目标对象
     * @return 解析后的集合对象
     */
    protected Object resolveCollection(PropertyTokenizer prop, Object object) {
        // 属性名为空，直接返回对象本身
        if ("".equals(prop.getName())) {
            return object;
        } else {
            // 否则通过 metaObject 获取属性值
            return metaObject.getValue(prop.getName());
        }
    }

    /**
     * 根据属性分词器和集合对象，获取集合中的指定元素。
     * 支持 Map、List、各种数组类型。
     *
     * @param prop       属性分词器，包含索引信息
     * @param collection 集合对象
     * @return 集合中的指定元素
     */
    protected Object getCollectionValue(PropertyTokenizer prop, Object collection) {
        // 如果是 Map，使用索引作为 key 获取 value
        if (collection instanceof Map) {
            return ((Map) collection).get(prop.getIndex());
        } else {
            // 将索引字符串转为整数
            int i = Integer.parseInt(prop.getIndex());
            if (collection instanceof List) {
                // 如果是 List，按索引取值
                return ((List) collection).get(i);
            } else if (collection instanceof Object[]) {
                // 如果是 Object 数组，按索引取值
                return ((Object[]) collection)[i];
            } else if (collection instanceof char[]) {
                // char 数组
                return ((char[]) collection)[i];
            } else if (collection instanceof boolean[]) {
                // boolean 数组
                return ((boolean[]) collection)[i];
            } else if (collection instanceof byte[]) {
                // byte 数组
                return ((byte[]) collection)[i];
            } else if (collection instanceof double[]) {
                // double 数组
                return ((double[]) collection)[i];
            } else if (collection instanceof float[]) {
                // float 数组
                return ((float[]) collection)[i];
            } else if (collection instanceof int[]) {
                // int 数组
                return ((int[]) collection)[i];
            } else if (collection instanceof long[]) {
                // long 数组
                return ((long[]) collection)[i];
            } else if (collection instanceof short[]) {
                // short 数组
                return ((short[]) collection)[i];
            } else {
                // 既不是 Map 也不是支持的数组或 List，抛出异常
                throw new RuntimeException("The '" + prop.getName() + "' property of " + collection + " is not a List or Array.");
            }
        }
    }

    /**
     * 根据属性分词器和集合对象，设置集合中指定元素的值。
     * 支持 Map、List、各种数组类型。
     *
     * @param prop       属性分词器，包含索引信息
     * @param collection 集合对象
     * @param value      要设置的新值
     */
    protected void setCollectionValue(PropertyTokenizer prop, Object collection, Object value) {
        if (collection instanceof Map) {
            // 如果是 Map，使用索引作为 key 设置 value
            ((Map) collection).put(prop.getIndex(), value);
        } else {
            int i = Integer.parseInt(prop.getIndex());
            // 将索引字符串转为整数
            if (collection instanceof List) {
                // 如果是 List，按索引设置值
                ((List) collection).set(i, value);
            } else if (collection instanceof Object[]) {
                // Object 数组
                ((Object[]) collection)[i] = value;
            } else if (collection instanceof char[]) {
                // char 数组，强制类型转换为 Character
                ((char[]) collection)[i] = (Character) value;
            } else if (collection instanceof boolean[]) {
                // boolean 数组
                ((boolean[]) collection)[i] = (Boolean) value;
            } else if (collection instanceof byte[]) {
                // byte 数组
                ((byte[]) collection)[i] = (Byte) value;
            } else if (collection instanceof double[]) {
                // double 数组
                ((double[]) collection)[i] = (Double) value;
            } else if (collection instanceof float[]) {
                // float 数组
                ((float[]) collection)[i] = (Float) value;
            } else if (collection instanceof int[]) {
                // int 数组
                ((int[]) collection)[i] = (Integer) value;
            } else if (collection instanceof long[]) {
                // long 数组
                ((long[]) collection)[i] = (Long) value;
            } else if (collection instanceof short[]) {
                // short 数组
                ((short[]) collection)[i] = (Short) value;
            } else {
                // 既不是 Map 也不是支持的数组或 List，抛出异常
                throw new RuntimeException("The '" + prop.getName() + "' property of " + collection + " is not a List or Array.");
            }
        }
    }

}
